package com.adwyxx.reflection;

import jdk.jfr.Label;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 使用反射读取注解信息：
 * <pre>
 * // 1. 获取类上的注解信息：
 * Class.getAnnotation(MyAnnotation.class);
 * // 2. 获取方法上的注解信息：
 * Method.getAnnotation(MyAnnotation.class);
 * // 3. 获取字段上的注解信息：
 * Field.getAnnotation(MyAnnotation.class);
 * // 4. 获取构造方法上的注解信息：
 * Constructor.getAnnotation(MyAnnotation.class);
 * // 5. 获取参数上的注解信息：
 * Parameter.getAnnotation(MyAnnotation.class);
 * // 6. 获取接口上的注解信息：
 * Interface.getAnnotation(MyAnnotation.class);
 * // 7. 获取包上的注解信息：
 * Package.getAnnotation(MyAnnotation.class);
 * </pre>
 *
 * @author Leo.W
 * @date 2024-09-11 15:16
 */
@MyAnnotation("Reflection Annotation Test")
public class AnnotationTest {
    @Label("Name")
    private String name;

    @MyAnnotation("AnnotationTest Constructor")
    public AnnotationTest(String name) {
        this.name = name;
    }

    @MyAnnotation("AnnotationTest#getName")
    public String getName() {
        return this.name;
    }

    public void setName(@MyAnnotation("setName parameter -> name") String name) {
        this.name = name;
    }

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        // 获取类上的注解信息
        MyAnnotation annotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
        System.out.println(annotation.value());

        // 获取构造函数上的注解信息：Constructor.getAnnotation
        Constructor<?> constructor = AnnotationTest.class.getConstructor(String.class);
        MyAnnotation annotation1 = constructor.getAnnotation(MyAnnotation.class);
        System.out.println(annotation1.value());

        // 获取方法上的注解信息：Method.getAnnotation(Annotation.class);
        Method method = AnnotationTest.class.getMethod("getName");
        MyAnnotation annotation2 = method.getAnnotation(MyAnnotation.class);
        System.out.println(annotation2.value());

        // 获取参数上的注解信息
        Method method1 = AnnotationTest.class.getMethod("setName", String.class);
        // Method.getParameterAnnotations() 返回一个二维数组，表示每一个参数对应的注解数组
        Annotation[][] annotations = method1.getParameterAnnotations();
        // annotations[0][0] 表示：第一个参数上的第一个注解
        MyAnnotation annotation3 = (MyAnnotation) annotations[0][0];
        System.out.println(annotation3.value());

        // 获取字段上的注解信息
        Field field = AnnotationTest.class.getDeclaredField("name");
        Label label = field.getAnnotation(Label.class);
        System.out.println(label.value());
    }
}
